package org.wabson.alfresco.translations;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

class BundleComparator
{
    private int totalMessages = 0, missingMessages = 0, extraMessages = 0, differentMessages = 0;

    public BundleComparisonResult compareKeysAndValues(MessageBundle mb1, MessageBundle mb2)
    {   
        BundleComparisonResult result = new BundleComparisonResult(mb2.getName(), mb1.getName());
        
        Properties p1 = mb1.getProperties();
        Properties p2 = mb2.getProperties();

        totalMessages += p1.size();
        result.setThisMessageCount(p2.size());
        result.setCompareToMessageCount(p1.size());

       for (String key : mergeEnumKeys(p1.propertyNames(), p2.propertyNames()))
       {
          String val1 = p1.getProperty(key);
          String val2 = p2.getProperty(key);
          if (val2 == null)
          {
              result.add(new MessageComparisonResult(key, val1, val2));
              missingMessages ++;
          }
          else if (val1 == null)
          {
              result.add(new MessageComparisonResult(key, val1, val2));
              extraMessages ++;
          }
          else if (!val2.equals(val1)) // Values are different
          {
              result.add(new MessageComparisonResult(key, val1, val2));
              differentMessages ++;
          }
       }

       return result;
    }

    public BundleComparisonResult compareKeys(MessageBundle mb1, MessageBundle mb2)
    {
        BundleComparisonResult result = new BundleComparisonResult(mb2.getName(), mb1.getName());
        
        Properties p1 = mb1.getProperties();
        Properties p2 = mb2.getProperties();

        totalMessages += p1.size();
        result.setThisMessageCount(p2.size());
        result.setCompareToMessageCount(p1.size());

       for (String key : mergeEnumKeys(p1.propertyNames(), p2.propertyNames()))
       {
          String val1 = p1.getProperty(key);
          String val2 = p2.getProperty(key);
            if (val2 == null)
            {
                result.add(new MessageComparisonResult(key, val1, val2));
                missingMessages ++;
            }
            else if (val1 == null)
            {
                result.add(new MessageComparisonResult(key, val1, val2));
                extraMessages ++;
            }
        }

        return result;
    }
    
    private static Set<String> mergeEnumKeys(Enumeration<?> e1, Enumeration<?> e2)
    {
        Set<String> keySet = new HashSet<String>();
        while (e1.hasMoreElements())
        {
            keySet.add((String) e1.nextElement());
        }
        while (e2.hasMoreElements())
        {
            keySet.add((String) e2.nextElement());
        }
        return keySet;
    }
    
    public void reset()
    {
        totalMessages = 0; missingMessages = 0; extraMessages = 0;
    }

    public int getTotalMessages()
    {
        return totalMessages;
    }

    public void setTotalMessages(int totalMessages)
    {
        this.totalMessages = totalMessages;
    }

    public int getMissingMessages()
    {
        return missingMessages;
    }

    public int getDifferentMessages()
    {
        return differentMessages;
    }

    public void setMissingMessages(int missingMessages)
    {
        this.missingMessages = missingMessages;
    }

    public int getExtraMessages()
    {
        return extraMessages;
    }

    public void setExtraMessages(int extraMessages)
    {
        this.extraMessages = extraMessages;
    }

    public void setDifferentMessages(int differentMessages)
    {
        this.differentMessages = differentMessages;
    }
}

class BundleComparisonResult
{
    
    private String baseFilePath;
    private String compareToFilePath;
    
    private MessageBundle baseBundle;
	private MessageBundle compareToBundle;
    
    private List<MessageComparisonResult> propertyComparisons;
    int thisMessageCount;
    int compareToMessageCount;

    /**
     * Create a new result object between two named bundles
     */
    public BundleComparisonResult(String baseFile, String compareToFile)
    {
        this.baseFilePath = baseFile;
        this.compareToFilePath = compareToFile;
        propertyComparisons = new ArrayList<MessageComparisonResult>();
    }

    public List<MessageComparisonResult> getPropertyComparisons()
    {
        return propertyComparisons;
    }

    public boolean add(MessageComparisonResult e)
    {
        return propertyComparisons.add(e);
    }
    
    public boolean isEmpty()
    {
        return propertyComparisons.isEmpty();
    }
    
    public int getNumMissingMessages()
    {
        int total = 0;
        for (MessageComparisonResult result : getPropertyComparisons())
        {
            if (result.getThisValue() == null)
            {
                total ++;
            }
        }
        return total;
    }
    
    public int getNumExtraMessages()
    {
        int total = 0;
        for (MessageComparisonResult result : getPropertyComparisons())
        {
            if (result.getCompareToValue() == null)
            {
                total ++;
            }
        }
        return total;
    }
    
    public int getNumIdenticalMessages()
    {
        int total = 0;
        for (MessageComparisonResult result : getPropertyComparisons())
        {
            if (result.getCompareToValue() == null && result.getThisValue() != null
                    && result.getCompareToValue().equals(result.getThisValue()))
            {
                total ++;
            }
        }
        return total;
    }
    
    public int getNumNonIdenticalMessages()
    {
        int total = 0;
        for (MessageComparisonResult result : getPropertyComparisons())
        {
            if (result.getCompareToValue() == null && result.getThisValue() != null
                    && !result.getCompareToValue().equals(result.getThisValue()))
            {
                total ++;
            }
        }
        return total;
    }

    public int getThisMessageCount()
    {
        return thisMessageCount;
    }

    public void setThisMessageCount(int thisMessageCount)
    {
        this.thisMessageCount = thisMessageCount;
    }

    public int getCompareToMessageCount()
    {
        return compareToMessageCount;
    }

    public void setCompareToMessageCount(int compareToMessageCount)
    {
        this.compareToMessageCount = compareToMessageCount;
    }

    public String getBaseFilePath()
    {
        return baseFilePath;
    }

    public void setBaseFilePath(String baseFilePath)
    {
        this.baseFilePath = baseFilePath;
    }

    public String getCompareToFilePath()
    {
        return compareToFilePath;
    }

    public void setCompareToFilePath(String compareToFilePath)
    {
        this.compareToFilePath = compareToFilePath;
    }
    public MessageBundle getBaseBundle() {
		return baseBundle;
	}

	public void setBaseBundle(MessageBundle baseBundle) {
		this.baseBundle = baseBundle;
	}

	public MessageBundle getCompareToBundle() {
		return compareToBundle;
	}

	public void setCompareToBundle(MessageBundle compareToBundle) {
		this.compareToBundle = compareToBundle;
	}
    
}

class MessageComparisonResult
{
    
    private String propertyName, thisValue, compareToValue;
    private int thisLineNumber, compareToLineNumber;

    public MessageComparisonResult(String propertyName, String compareToValue,
            String thisValue)
    {
        this.propertyName = propertyName;
        this.thisValue = thisValue;
        this.compareToValue = compareToValue;
    }

    public int getThisLineNumber()
    {
        return thisLineNumber;
    }

    public void setThisLineNumber(int thisLineNumber)
    {
        this.thisLineNumber = thisLineNumber;
    }

    public int getCompareToLineNumber()
    {
        return compareToLineNumber;
    }

    public void setCompareToLineNumber(int compareToLineNumber)
    {
        this.compareToLineNumber = compareToLineNumber;
    }

    public String getPropertyName()
    {
        return propertyName;
    }

    public void setPropertyName(String propertyName)
    {
        this.propertyName = propertyName;
    }

    public String getThisValue()
    {
        return thisValue;
    }

    public void setThisValue(String thisValue)
    {
        this.thisValue = thisValue;
    }

    public String getCompareToValue()
    {
        return compareToValue;
    }

    public void setCompareToValue(String compareToValue)
    {
        this.compareToValue = compareToValue;
    }
    
}
